package zheezes.eisp.fep.model;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import zheezes.model.ObservableModel;
import zheezes.util.ArrayUtil;


public class Commander extends ObservableModel {
	private String host;
	private int port;
	private Socket socket;
	private InputStream in;
	private OutputStream out;

	public int connect(String host, int port) {
		try {
			socket = new Socket(host, port);
			socket.setSoTimeout(3000);
			in = socket.getInputStream();
			out = socket.getOutputStream();
			firePropertyChange("connected", false, true);
		} catch (IOException e) {
			e.printStackTrace();
			return -1;
		}
		return 0;
	}

	public int connect() {
		return connect(host, port);
	}

	public void close() {
		try {
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			firePropertyChange("connected", true, false);
		}
	}

	public String command(String cmd) {
		byte[] buffer = new byte[65536];
		int length = 0;
		int len = 0;
		int index = 0;
		try {
			out.write(cmd.getBytes());
			out.write(0x00);
			while ((len = in.read(buffer, length, buffer.length - length)) >= 0) {
				length += len;
				if ((index = ArrayUtil.find(buffer, 0, length, (byte) 0x00)) >= 0) {
					return new String(buffer, 0, index);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			close();
		}
		return null;
	}

	public boolean isConnected() {
		if (socket != null && !socket.isClosed()) {
			return true;
		}
		return false;
	}

	public Map<String, Integer> count() {
		Map<String, Integer> map = null;
		String result = command("count");
		if (result != null) {
			map = new HashMap<String, Integer>();
			String[] lines = result.split("\n");
			for (String line : lines) {
				if (line.matches(".*tcp.*")) {
					int idx = line.indexOf('=');
					map.put("tcp", Integer.parseInt(line.substring(idx + 1)
							.trim()));
				} else if (line.matches(".*udp.*")) {
					int idx = line.indexOf('=');
					map.put("udp", Integer.parseInt(line.substring(idx + 1)
							.trim()));
				}
			}
		}
		return map;
	}

	public static void main(String[] args) {
		Commander cmder = new Commander();
		DateFormat dfmt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		cmder.connect("192.168.100.84", 8887);
		for (;;) {
			System.out.printf("%s\n%s\n", dfmt.format(Calendar.getInstance()
					.getTime()), cmder.command("hhh"));
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				return;
			}
		}
	}

	public String getHost() {
		return host;
	}

	public void setHost(String host) {
		String old = this.host;
		this.host = host;
		firePropertyChange("host", old, host);
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		int old = this.port;
		this.port = port;
		firePropertyChange("port", old, port);
	}
}
